package org.planx.xmlstore.routing;

import java.io.*;
import java.math.*;
import java.net.*;
import java.util.*;
import junit.framework.*;
import org.planx.xmlstore.routing.messaging.*;
import org.planx.xmlstore.routing.operation.*;

public abstract class RoutingTestCase extends TestCase {
    private static final Object DUMMY = new Object();

    public RoutingTestCase(String s) {
        super(s);
    }

    public static String readFile(String filename) throws IOException {
        BufferedReader in = new BufferedReader(new FileReader(filename));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
            sb.append('\n');
        }
        in.close();
        return sb.toString();
    }

    public static Node newRandomNode() {
        try {
            return new Node(InetAddress.getLocalHost(), 4000,
                              Identifier.randomIdentifier());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Node newXorNode(Node node, int val) {
        try {
            // Ensure firstSeen time stamps can be differentiated
            synchronized (DUMMY) {
                DUMMY.wait(10);
            }
            return new Node(InetAddress.getLocalHost(), 4000, newXorId(node, val));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Identifier newXorId(Node node, int val) {
        byte[] b = new byte[2];
        b[0] = 0;
        b[1] = (byte) val;
        return new Identifier((new BigInteger(b)).xor(node.getId().value()));
    }

    public static Identifier newAbsId(int val) {
        byte[] b = {(byte) val};
        return new Identifier(b);
    }

    public static List getClosestOrdered(Space space, Identifier id) {
        List nodes = space.getClosestNodes(id);
        Collections.sort(nodes, new Node.DistanceComparator(id));
        return nodes;
    }

    public static void orderNodes(List nodes) {
        orderNodes(nodes, new Identifier());
    }

    public static void orderNodes(List nodes, Identifier id) {
        Collections.sort(nodes, new Node.DistanceComparator(id));
    }

    public static String toXorNodeString(Node relnode, List nodes) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int i = 0; i < nodes.size(); i++) {
            Node node = (Node) nodes.get(i);
            if (i > 0) sb.append(",");
            sb.append(Identifier.toBinary(node.getId().value().xor(relnode.getId().value())));
        }
        sb.append("]");
        return sb.toString();
    }

    public static String toNodeIdString(List nodes) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int i = 0; i < nodes.size(); i++) {
            Node node = (Node) nodes.get(i);
            if (i > 0) sb.append(",");
            sb.append(node.getId());
        }
        sb.append("]");
        return sb.toString();
    }

    public static String toString(byte[] b) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int i = 0; i < b.length; i++) {
            if (i > 0) sb.append(",");
            String s = Integer.toHexString((int) b[i]);
            s = (s.length() > 1) ? s.substring(s.length()-2) : "0"+s;
            sb.append(s);
        }
        sb.append("]");
        return sb.toString();
    }
}
